package ws

import (
	"crypto/sha1"
	"encoding/base64"
	"io"
	"io/ioutil"
	"log"
	"net"
	"net/http"
	"time"
)

type WsManager struct {
	WsPool   []WsSocket
	Listener net.Listener
}

// var wg sync.WaitGroup

func (wsManager *WsManager) Listen(port string) {
	go listen(port)
	log.Println("Ws Listen at port: " + port)

	http.HandleFunc("/index", func(rw http.ResponseWriter, r *http.Request) {
		file, err := ioutil.ReadFile("index.html")
		if err != nil {
			log.Panic(err)
			return
		}
		rw.Write(file)
	})
	http.ListenAndServe(":8002", nil)
}

func listen(port string) {
	l, err := net.Listen("tcp", port)
	if err != nil {
		log.Panic("tcp 异常:", err)
	}
	WsManagerInstance.Listener = l

	for {
		c, err := l.Accept()
		if err != nil {
			log.Panic("accept 异常", err)
		}
		handleConnection(c)
	}
}

var WsManagerInstance = &WsManager{}

func handleConnection(conn net.Conn) {
	log.Print("开始接收连接.")

	// 声明接口数据的切片
	buf := make([]byte, 1024)

	// 从conn里读取数据到变更buf
	_, err := conn.Read(buf)
	log.Println(string(buf))
	if err != nil {
		log.Panic("读取数据异常", err)
		conn.Close()
		return
	}

	isGet := false
	if string(buf[0:3]) == "GET" {
		isGet = true
	}

	log.Printf("isGet: %t", isGet)

	if isGet {
		headers := parseHandsanke(string(buf))
		// log.Println("headers", headers)

		// 取出： Sec-WebSocket-Key
		secWebsocketKey := headers["Sec-WebSocket-Key"]
		log.Println("Sec-WebSocket-Key", secWebsocketKey)

		// 魔数uuid, 参考：https://datatracker.ietf.org/doc/html/rfc6455， http://cn.voidcc.com/question/p-oauwjhqm-bdr.html
		uuid := "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
		log.Println("accept raw:", secWebsocketKey+uuid)

		// 使用sha1加密
		h := sha1.New()
		io.WriteString(h, secWebsocketKey+uuid)

		accept := make([]byte, 28)
		base64.StdEncoding.Encode(accept, h.Sum(nil))
		log.Println("accept", string(accept))

		// 生成response
		response := "HTTP/1.1 101 Switching Protocols\r\n"
		response = response + "Sec-WebSocket-Accept: " + string(accept) + "\r\n"
		response = response + "Connection: Upgrade\r\n"
		response = response + "Upgrade: websocket\r\n\r\n"

		log.Println("response", response)

		// 通过conn输出response
		length, err := conn.Write([]byte(response))
		if err != nil {
			conn.Close()
			log.Panic("输出Response异常", err)
		}
		log.Println("输出长度", length)

		// 声明WSSocket
		ws := NewWsSocket(conn)

		for {
			data, err := ws.ReadIframe()
			if err != nil {
				log.Fatal("收到数据异常", err)
			}
			log.Println("接收到数据：", string(data))
			if len(data) == 0 {
				break
			}
			ws.SendIframe([]byte("这是服务器返回内容:" + time.Now().String()))
		}
		log.Println("ending")

	} else {
		conn.Write([]byte("异常的HTTP METHOD"))
	}
}
